using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class AnalogController : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerEnterHandler, IEventSystemHandler
{
	public delegate void AnalogStickAction(AnalogType type, AnalogData data);

	public AnalogData analogData;

	[SerializeField]
	private Image jsBackground;

	[SerializeField]
	private Image analogstick;

	[SerializeField]
	private AnalogType analogType;

	private int MAX_DISTANCE;

	private int restrictValue;

	private Vector2 firstTouchPos;

	private float currDistance;

	private Vector3 jsPos;

	private int currPointerId = -1;

	private int fingerId;

	private bool prevStatus;

	protected bool isFingerOnScreen;

	private readonly Vector2 v2_zero = Vector2.zero;

	private Vector2 curPos;

	public static event AnalogStickAction OnAnalogstickValueChange;

	private void Start()
	{
		MAX_DISTANCE = (int)((jsBackground.rectTransform.rect.width - (float)restrictValue) / 2f);
	}

	private void OnEnable()
	{
		base.transform.localPosition = Vector3.zero;
		analogData = new AnalogData(v2_zero, v2_zero, false);
	}

	protected void Update()
	{
		curPos = new Vector2(base.transform.localPosition.x / (float)MAX_DISTANCE, base.transform.localPosition.y / (float)MAX_DISTANCE);
		if (analogData.axes != curPos)
		{
			analogData.deltaPosition = curPos - analogData.axes;
			analogData.axes = curPos;
		}
		else
		{
			analogData.deltaPosition = v2_zero;
		}
		if (AnalogController.OnAnalogstickValueChange != null && (analogData.isActive || prevStatus))
		{
			if (!analogData.isActive)
			{
				prevStatus = analogData.isActive;
			}
			AnalogController.OnAnalogstickValueChange(analogType, analogData);
		}
		if (!analogData.isActive)
		{
			return;
		}
		isFingerOnScreen = false;
		Touch[] touches = Input.touches;
		foreach (Touch touch in touches)
		{
			if (touch.fingerId == fingerId)
			{
				isFingerOnScreen = true;
				break;
			}
		}
		if (!isFingerOnScreen)
		{
			Deactivate();
		}
	}

	protected void Deactivate()
	{
		base.transform.localPosition = Vector3.zero;
		base.transform.localScale = Vector3.one;
		currPointerId = -1;
		prevStatus = analogData.isActive;
		analogData.isActive = false;
	}

	public void OnBeginDrag(PointerEventData eventData)
	{
		if (eventData.pointerId < Input.touchCount && Input.touchCount > 0)
		{
			if (analogData.isActive && Input.GetTouch(eventData.pointerId).fingerId != fingerId)
			{
				eventData.pointerDrag = null;
				return;
			}
			eventData.pointerDrag = base.gameObject;
			prevStatus = analogData.isActive;
			analogData.isActive = true;
			fingerId = Input.GetTouch(eventData.pointerId).fingerId;
			currPointerId = eventData.pointerId;
			firstTouchPos = analogstick.rectTransform.position * Values.Instance.CanvasScale;
		}
		else
		{
			eventData.pointerDrag = null;
		}
	}

	public void OnDrag(PointerEventData eventData)
	{
		if (Input.touchCount > 0)
		{
			for (int i = 0; i < Input.touchCount; i++)
			{
				if (fingerId == Input.GetTouch(i).fingerId)
				{
					currPointerId = i;
					break;
				}
			}
		}
		if (!analogData.isActive || currPointerId <= -1 || Input.touchCount <= currPointerId)
		{
			return;
		}
		jsPos = Input.GetTouch(currPointerId).position * Values.Instance.CanvasScale - firstTouchPos;
		currDistance = Vector3.Distance(jsPos, Vector3.zero);
		if (currDistance <= (float)MAX_DISTANCE)
		{
			base.transform.localPosition = jsPos;
		}
		else
		{
			float f = Mathf.Atan(jsPos.y / jsPos.x);
			if (jsPos.x < 0f)
			{
				base.transform.localPosition = new Vector3((float)MAX_DISTANCE * (0f - Mathf.Cos(f)), (float)MAX_DISTANCE * (0f - Mathf.Sin(f)), 0f);
			}
			else
			{
				base.transform.localPosition = new Vector3((float)MAX_DISTANCE * Mathf.Cos(f), (float)MAX_DISTANCE * Mathf.Sin(f), 0f);
			}
		}
		base.transform.localScale = new Vector3(1.25f, 1.25f, 1f);
	}

	public void OnEndDrag(PointerEventData eventData)
	{
		if (analogData.isActive)
		{
			Deactivate();
			eventData.pointerDrag = null;
		}
	}

	public void OnPointerEnter(PointerEventData eventData)
	{
		if (eventData.pointerId > -1 && eventData.pointerDrag == null && eventData.pointerEnter == base.gameObject)
		{
			OnBeginDrag(eventData);
		}
	}
}
